import logging
import math
from typing import Optional, List

from fastapi import APIRouter, Depends, Query, Path
from pydantic import Field, BaseModel
from sqlalchemy import text
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
from commons.BaseResponse import BaseResponse
from commons.PaginationBase import PaginationBase
from datebase import get_db
from utils.EncryptionUtil import oauth2_scheme, EncryptionMiddleware

mm_item_head = APIRouter(prefix="/maintain/mmitemHead", tags=["保养项目管理"], dependencies=[Depends(oauth2_scheme)])


class MaintenanceItemSearch(PaginationBase):
    # 筛选条件
    feuipmentid: Optional[str] = Field("", description="设备ID")
    fmmlevelno: Optional[str] = Field("", description="保养等级编号")


class MaintenanceItemDetail(BaseModel):
    """保养项目明细"""
    fline: int = Field(..., description="明细行号")
    fmmitemno: str = Field(..., description="保养项目编号")
    fmmitemname: str = Field(..., description="保养项目名称")
    fmmflag: int = Field(..., description="保养标志")
    fmemo: Optional[str] = Field("", description="备注")
    fmmresult: int = Field(0, description="保养结果")
    fstate: int = Field(1, description="状态")


class MaintenanceItemCreate(BaseModel):
    """保养项目新增请求参数"""
    fbillno: str = Field(..., description="单据编号")
    feuipmentid: str = Field(..., description="设备ID")
    fmmlevelno: str = Field(..., description="保养等级编号")
    fmmworktime: str = Field(..., description="保养工时")
    fupddate: str = Field(..., description="更新日期(yyyy-MM-dd HH:mm:ss)")
    foperator: Optional[str] = Field("0", description="操作人")
    fmemo: Optional[str] = Field("", description="备注")
    details: List[MaintenanceItemDetail] = Field(..., description="保养项目明细列表")


@mm_item_head.get("/list", summary="保养项目查询接口")
def list_mm_item_head(search: MaintenanceItemSearch = Query(), db: Session = Depends(get_db)):
    param = {}
    sql = "select count(1) from lims.s_tc_mmitem_head where 1=1"
    if search.feuipmentid != "":
        sql = sql + " and feuipmentid = :feuipmentid "
        param["feuipmentid"] = search.feuipmentid
    if search.fmmlevelno != "":
        sql = sql + " and fmmlevelno = :fmmlevelno "
        param["fmmlevelno"] = search.fmmlevelno
    count = db.execute(text(sql), param).scalar()
    param = {}
    sql = "select fbillno,feuipmentid,fmmlevelno,fmmworktime,fmemo,fupddate,foperator"
    sql = sql + " from lims.s_tc_mmitem_head where 1=1"
    if search.feuipmentid != "":
        sql = sql + " and feuipmentid = :feuipmentid "
        param["feuipmentid"] = search.feuipmentid
    if search.fmmlevelno != "":
        sql = sql + " and fmmlevelno = :fmmlevelno "
        param["fmmlevelno"] = search.fmmlevelno
    if search.order == "desc":
        sql = sql + " order by  feuipmentid,fmmlevelno desc "
    else:
        sql = sql + " order by  fmmlevelno ,fmmlevelno  "
    sql = sql + " limit :limit offset :offset "
    param["offset"] = search.offset
    param["limit"] = search.limit
    data = db.execute(text(sql), param).fetchall()

    data_list = []
    for key in range(len(data)):
        d1 = {}
        d1['fbillno'] = data[key][0]
        d1['feuipmentid'] = data[key][1]
        d1['fmmlevelno'] = data[key][2]
        d1['fmmworktime'] = data[key][3]
        d1['fmemo'] = data[key][4]
        d1['fupddate'] = data[key][5]
        d1['foperator'] = data[key][6]
        data_list.append(d1)

    info_dict = {"list": data_list,
                 "limit": search.limit,
                 "page": search.pageIndex,
                 "pages": (count + search.limit - 1) // search.limit,
                 "total": count}
    return BaseResponse.success(data=info_dict)


@mm_item_head.post("/create", summary="保养项目新增接口")
def create_mm_item_head(create: MaintenanceItemCreate, db: Session = Depends(get_db)):
    try:
        fbillno = create.fbillno
        # 返回内容
        d1 = {}
        detail_list = []
        with db.begin():
            jsondata = create.details
            for data in jsondata:
                sql = "insert into lims.s_tc_mmitem_detail(fbillno,fline,fmmitemno,fmmitemname,fmmflag,fmemo,fmmresult,fstate)"
                sql = sql + " values( :fbillno , :fline , :fmmitemno , :fmmitemname , :fmmflag , :fmemo ,0,1)"
                db.execute(text(sql), {
                    "fbillno": fbillno,
                    "fline": data.fline,
                    "fmmitemno": data.fmmitemno,
                    "fmmitemname": data.fmmitemname,
                    "fmmflag": data.fmmflag,
                    "fmemo": data.fmemo,
                })

                # 返回明细
                d2 = {}
                d2['fbillno'] = fbillno
                d2['fline'] = data.fline
                d2['fmmitemno'] = data.fmmitemno
                d2['fmmitemname'] = data.fmmitemname
                d2['fmmflag'] = float(data.fmmflag)
                d2['fmmresult'] = float(data.fmmresult)
                d2['fstate'] = float(data.fstate)
                d2['fmemo'] = data.fmemo
                detail_list.append(d2)
            sql = "insert into lims.s_tc_mmitem_head(fbillno,feuipmentid,fmmlevelno,fmmworktime,fmemo,fupddate,foperator)"
            sql = sql + " values( :fbillno , :feuipmentid , :fmmlevelno , :fmmworktime , :fmemo , :fupddate , :foperator )"
            db.execute(text(sql), {
                "fbillno": fbillno,
                "feuipmentid": create.feuipmentid,
                "fmmlevelno": create.fmmlevelno,
                "fmmworktime": create.fmmworktime,
                "fmemo": create.fmemo,
                "fupddate": create.fupddate,
                "foperator": create.foperator,
            })
            # 返回
            d1['fbillno'] = fbillno
            d1['feuipmentid'] = create.feuipmentid
            d1['fmmlevelno'] = create.fmmlevelno
            d1['fmmworktime'] = create.fmmworktime
            d1['fmemo'] = create.fmemo
            d1['fupddate'] = create.fupddate
            d1['foperator'] = create.foperator
            d1["details"] = detail_list
            return BaseResponse.success(data=d1)
    except SQLAlchemyError as e:
        # 发生异常时自动回滚
        db.rollback()
        # 记录错误日志
        logging.error(f"数据库错误: {str(e)}")
        # 返回错误响应
        return BaseResponse.error(message="数据库操作失败")
    except Exception as e:
        db.rollback()
        logging.error(f"未知错误: {str(e)}")
        return BaseResponse.error(message="令牌过期")


@mm_item_head.post("/update", summary="保养项目修改接口")
def update_mm_item_head(update: MaintenanceItemCreate, db: Session = Depends(get_db)):
    try:
        fbillno = update.fbillno
        with db.begin():
            sql = "delete from lims.s_tc_mmitem_detail where fbillno= :fbillno "
            db.execute(text(sql), {
                "fbillno": fbillno,
            })
            jsondata = update.details
            for data in jsondata:
                sql = "insert into lims.s_tc_mmitem_detail(fbillno,fline,fmmitemno,fmmitemname,fmmflag,fmemo,fmmresult,fstate)"
                sql = sql + " values( :fbillno , :fline , :fmmitemno , :fmmitemname , :fmmflag , :fmemo ,0,1)"
                db.execute(text(sql), {
                    "fbillno": fbillno,
                    "fline": data.fline,
                    "fmmitemno": data.fmmitemno,
                    "fmmitemname": data.fmmitemname,
                    "fmmflag": data.fmmflag,
                    "fmemo": data.fmemo,
                })
            sql = "update lims.s_tc_mmitem_head "
            sql = sql + " set fmemo= :fmemo "
            sql = sql + ",fmmworktime= :fmmworktime ,fmmlevelno= :fmmlevelno "
            sql = sql + ",fupddate= :fupddate ,foperator= :foperator "
            sql = sql + " where fbillno= :fbillno "
            db.execute(text(sql), {
                "fmemo": update.fmemo,
                "fmmworktime": update.fmmworktime,
                "fmmlevelno": update.fmmlevelno,
                "fupddate": update.fupddate,
                "foperator": update.foperator,
                "fbillno": fbillno,
            })
            return BaseResponse.success()
    except SQLAlchemyError as e:
        # 发生异常时自动回滚
        db.rollback()
        # 记录错误日志
        logging.error(f"数据库错误: {str(e)}")
        # 返回错误响应
        return BaseResponse.error(message="数据库操作失败")
    except Exception as e:
        db.rollback()
        logging.error(f"未知错误: {str(e)}")
        return BaseResponse.error(message="令牌过期")


@mm_item_head.post("/delete/{fbillno}", summary="保养项目删除接口")
def delete_mm_item_head(fbillno: str, db: Session = Depends(get_db)):
    try:
        with db.begin():
            sql = "delete from lims.s_tc_mmitem_detail where fbillno= :fbillno "
            db.execute(text(sql), {
                "fbillno": fbillno,
            })
            sql = "delete from lims.s_tc_mmitem_head where fbillno= :fbillno "
            db.execute(text(sql), {
                "fbillno": fbillno,
            })
            return BaseResponse.success()
    except SQLAlchemyError as e:
        # 发生异常时自动回滚
        db.rollback()
        # 记录错误日志
        logging.error(f"数据库错误: {str(e)}")
        # 返回错误响应
        return BaseResponse.error(message="数据库操作失败")
    except Exception as e:
        db.rollback()
        logging.error(f"未知错误: {str(e)}")
        return BaseResponse.error(message="令牌过期")
